
import Foundation

enum IdsType: Int {
    case user
    case group
    case friend
    case member
    case dapp
    
    init(rawValue: Int) {
        switch rawValue {
        case 0: self = .user
        case 1: self = .group
        case 2: self = .friend
        case 3: self = .member
        case 4: self = .dapp
        default: self = .user
        }
    }
}
actor IdQueue {
    var mIds: [(IdsType,String)] = []
    func get() -> (IdsType,String)? {
        guard let ids = mIds.first else {return nil}
        mIds.removeFirst()
        return ids
    }
    func set(_ type:IdsType, _ osnId:String) {
        mIds.append((type, osnId))
    }
}

class IdService {
    private var mQueue = IdQueue()
    
    func initService(){
        Task {
            while(true){
                if let ids = await mQueue.get() {
                    print("refresh id: \(ids)")
                    switch ids.0 {
                    case .user: await refreshUser(ids.1)
                    case .group: await refreshGroup(ids.1)
                    case .friend: await refreshFriend(ids.1)
                    case .member: await refreshMember(ids.1)
                    case .dapp: await refreshDapp(ids.1)
                    }
                }else{
                    usleep(100000)
                }
            }
        }
    }
    func refreshId(_ type:IdsType, _ osnId:String) async {
        await mQueue.set(type, osnId)
    }
    private func refreshUser(_ osnId:String) async {
        if let user = await gosnUser.fetchUserInfo(osnId) {
            geventService.post(OsnEvent.UserInfoUpdated, user)
        }
    }
    private func refreshGroup(_ osnId:String) async {
        if let group = await gosnGroup.fetchGroupInfo(osnId) {
            geventService.post(OsnEvent.GroupInfoUpdated, group)
        }
    }
    private func refreshFriend(_ osnId:String) async {
        if let friend = await gosnFriend.fetchFriendInfo(osnId) {
            geventService.post(OsnEvent.FriendInfoUpdated, friend)
        }
    }
    private func refreshMember(_ osnId:String) async {
        guard let group = gosnGroup.getGroupInfo(osnId) else {return}
        var members:[DMCCMember] = []
        var begin = 0;
        while(begin < group.memberCount){
            members += await gosnMember.updateMemberZone(osnId, begin, 25)
            begin += 25
        }
        geventService.post(OsnEvent.GroupMemberUpdated, members)
    }
    private func refreshDapp(_ osnId:String) async {
        if let dapp = await gosnDapp.fetchDappInfo(osnId) {
            geventService.post(OsnEvent.NewDapp, dapp)
        }
    }
}
let gidService = IdService()
